﻿using System;
using Castle.DynamicProxy;

namespace AopDemo
{
    public class MyInterceptor : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            PreProceed(invocation);
            invocation.Proceed();
            PostProceed(invocation);
        }
        public void PreProceed(IInvocation invocation)
        {
            Console.WriteLine("方法执行前");
        }

        public void PostProceed(IInvocation invocation)
        {
            Console.WriteLine("方法执行后");
        }
    }
    public interface IUserProcessorByCastle
    {
        void RegUser(User user);
    }

    public class UserProcessorByCastle1 : IUserProcessorByCastle
    {
        public virtual void RegUser(User user)
        {
            Console.WriteLine("CastleClient1用户已注册。Name:{0},PassWord:{1}", user.Name, user.PassWord);
        }
    }
    public class UserProcessorByCastle2 : IUserProcessorByCastle
    {
        public  void RegUser(User user)
        {
            Console.WriteLine("CastleClient2用户已注册。Name:{0},PassWord:{1}", user.Name, user.PassWord);
        }
    }

    public class CastleClient
    {
        public static void Run()
        {
            try
            {
                ProxyGenerator generator = new ProxyGenerator();//实例化【代理类生成器】  
                MyInterceptor interceptor = new MyInterceptor();//实例化【拦截器】  
                //CreateClassProxy返回的对象类型不是UserProcessorByCastle,而是使用UserProcessorByCastle作为基类动态生成的一个类型,就是产生了一个继承自原来的对象的代理类（就是一个子类），
                //因此每个要被拦截的方法必须使用virtual，子类才可以重写父类的方法，也就是代理类才可以正确执行
                //使用【代理类生成器】创建UserProcessorByCastle对象，而不是使用new关键字来实例化  
                UserProcessorByCastle1 userprocessor = generator.CreateClassProxy<UserProcessorByCastle1>(interceptor);
               
                User user = new User() { Name = "lee", PassWord = "123123123123" };
                userprocessor.RegUser(user);

                var userprocessor2=generator.CreateInterfaceProxyWithTarget<IUserProcessorByCastle>(new UserProcessorByCastle2(), interceptor);
                userprocessor2.RegUser(user);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
